package com.meta.builder;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson2.JSONObject;
import com.alibaba.fastjson2.annotation.JSONField;
import com.meta.annotation.MetaGenAnnotation;
import com.meta.annotation.MetaMapper;
import com.meta.builder.freemarker.field.ClassInfo;
import com.meta.internal.Options;
import freemarker.template.Template;

import javax.annotation.processing.ProcessingEnvironment;
import javax.lang.model.element.Element;
import javax.tools.Diagnostic;
import javax.tools.JavaFileObject;
import java.io.IOException;
import java.io.Writer;
import java.util.List;
import java.util.Map;

/**
 * 模板配置
 */
public abstract class IMetaTemplate {
    protected ClassInfo classInfo;
    protected static final String IMPLEMENTATION_SUFFIX = "DTO";
    @JSONField(deserialize = false)
    protected String clsPath;
    protected String clsPackage;
    @JSONField(deserialize = false)
    protected Options options;
    @JSONField(deserialize = false)
    protected Element element;

    public void initTemplate(Element element, Options options) {
        this.options = options;
        this.element = element;
        this.clsPath = options.getProcessingEnv().getElementUtils().getPackageOf(element).getQualifiedName().toString()+"."+ StrUtil.lowerFirst(element.getSimpleName());
        this.clsPackage = clsPath;
    }

    /**
     * 模板
     *
     * @return
     */
    public abstract Template getTemplate();
    /**
     * 读取模板文件
     * @param clazz 类
     * @return
     */
    protected String getTemplateNameForClass(Class<?> clazz) {
        return clazz.getSimpleName() + ".ftl";
    }
    /**
     * 入参
     *
     * @return
     */
    public Map<String, Object> getParamMap() {
        return BeanUtil.beanToMap(this);
    }

    /**
     * 解析类型
     *
     * @param object
     * @param baseName
     * @return
     */
    public abstract List<ClassInfo> builder(JSONObject object, String baseName, Map<String, MetaMapper> mappers, MetaGenAnnotation[] metaAnnotations);

    public void writer(ProcessingEnvironment processingEnv, String clsContext) throws IOException {
        JavaFileObject fileObject = processingEnv.getFiler().createSourceFile(this.clsPath + "." + getClsName());
        Writer writer = fileObject.openWriter();
        writer.write(clsContext);
        writer.flush();
        writer.close();
    }

    public String getClsName() {
        return classInfo.getClsName();
    }

    public ClassInfo getClassInfo() {
        return classInfo;
    }

    public void setClassInfo(ClassInfo classInfo) {
        this.classInfo = classInfo;
    }
}